package com.mezz.bones.framework.outbox.job;

import com.mezz.bones.framework.outbox.domain.entity.OutboxMessage;
import com.mezz.bones.framework.outbox.domain.entity.OutboxMessageArchive;
import com.mezz.bones.framework.outbox.enums.MessageStatusEnum;
import com.mezz.bones.framework.outbox.repository.IOutboxMessageArchiveRepository;
import com.mezz.bones.framework.outbox.repository.IOutboxMessageRepository;
import com.mezz.bones.framework.outbox.service.OutboxArchiveService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class OutboxArchiveJob {

    private final IOutboxMessageRepository outboxMessageRepository;
    private final OutboxArchiveService outboxArchiveService;
    
    private static final int BATCH_SIZE = 100;
    
    /**
     * 每天凌晨2点执行归档任务
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void archiveCompletedMessages() {
        log.info("开始执行消息归档任务");
        
        try {
            // 查询7天前的已完成或已取消消息
            LocalDateTime archiveTime = LocalDateTime.now().minusDays(7);
            Date archiveDate = Date.from(archiveTime.atZone(ZoneId.systemDefault()).toInstant());
            
            int totalArchived = 0;
            List<OutboxMessage> messagesToArchive;
            
            do {
                // 分批查询需要归档的消息
                messagesToArchive = outboxMessageRepository.findMessagesToArchive(
                        archiveDate,
                        BATCH_SIZE // 每批处理100条
                );
                
                if (!messagesToArchive.isEmpty()) {
                    log.info("找到{}条需要归档的消息", messagesToArchive.size());
                    
                    // 执行归档
                    outboxArchiveService.archiveMessages(messagesToArchive);
                    
                    totalArchived += messagesToArchive.size();
                    log.info("已归档{}条消息，总计{}条", messagesToArchive.size(), totalArchived);
                }
                
            } while (!messagesToArchive.isEmpty());
            
            log.info("消息归档任务执行完成，共归档{}条消息", totalArchived);
        } catch (Exception e) {
            log.error("执行消息归档任务异常", e);
        }
    }
}